import request from "request-promise";
import { sign } from "./utils";
const baseUrl = "https://api.weixin.qq.com/cgi-bin/";
const urlConfig = {
  access_token_url: baseUrl + "token?grant_type=client_credential&",
  tag: {
    create: baseUrl + "tags/create?access_token=", //创建
    fetch: baseUrl + "tags/get?access_token=", //获取
    update: baseUrl + "tags/update?access_token=", //更新
    del: baseUrl + "tags/delete?access_token=", //删除
    fetchUsers: baseUrl + "user/tag/get?access_token=", //粉丝列表
    batchTag: baseUrl + "tags/members/batchtagging?access_token=", //批量为用户打标签
    batchUntag: baseUrl + "tags/members/batchuntaggingaccess_token=", //批量为用户取消标签
    getidlist: baseUrl + "/tags/getidlist?access_token=" //获取用户身上的标签列表
  },
  user: {
    remark: baseUrl + "user/info/updateremark?access_token=", //设置用户备注名
    info: baseUrl + "user/info?access_token=", //获取用户基本信息(UnionID机制)
    batchInfo: baseUrl + "user/info/batchget?access_token=", //批量获取用户基本信息
    fetchUserList: baseUrl + "user/get?access_token=", //获取用户列表
    getBlackList: baseUrl + "tags/members/getblacklist?access_token=", //黑名单管理
    batchBlackUsers: baseUrl + "tags/members/batchblacklist?access_token=", //拉黑用户
    batchUnblackUsers: baseUrl + "tags/members/batchunblacklist?access_token=" //取消拉黑用户
  },
  menu: {
    create: baseUrl + "menu/create?access_token=", //创建
    get: baseUrl + "menu/get?access_token=", //获取
    del: baseUrl + "menu/delete?access_token=", //删除
    addCondition: baseUrl + "menu/addconditional?access_token=", //创建个性化菜单
    delCondition: baseUrl + "menu/delconditional?access_token=", //删除个性化菜单
    getInfo: baseUrl + "get_current_selfmenu_info?access_token=" //获取菜单配置
  },
  ticket: {
    fetch: baseUrl + "ticket/getticket?access_token="
  }
};

export default class Wecht {
  constructor(opt) {
    this.opt = Object.assign({}, opt);
    this.appID = opt.appID;
    this.appsecret = opt.appsecret;
    this.getAccessToken = opt.getAccessToken;
    this.saveAccessToken = opt.saveAccessToken;
    this.getTicket = opt.getTicket;
    this.saveTicket = opt.saveTicket;
  }

  // 请求函数
  async request(options) {
    options = Object.assign({}, options, { json: true });
    try {
      const res = await request(options);
      return res;
    } catch (e) {
      console.error(e);
    }
  }

  // 请求票据
  async fetchAccessToken() {
    const token = await this.getAccessToken();
    if (this.validData(token, "access_token")) {
      return token;
    } else {
      return await this.updateAccessToken();
    }
  }

  // 刷新票据
  async updateAccessToken() {
    try {
      const res = await this.request({
        uri:
          urlConfig.access_token_url +
          `appid=${this.appID}&secret=${this.appsecret}`
      });
      if (res.access_token && res.expires_in) {
        const restoken = {
          access_token: res.access_token,
          expires_in: new Date().getTime() + (res.expires_in - 20) * 1000
        };
        await this.saveAccessToken(restoken);
        return res;
      } else {
        console.log("未获取access_token");
        return false;
      }
    } catch (e) {
      console.error(e);
    }
  }

  // ticket
  async fetchTicket() {
    const ticket = await this.getTicket();
    if (this.validData(ticket, "ticket")) {
      return ticket;
    } else {
      return await this.updateTicket();
    }
  }

  // 刷新票据
  async updateTicket() {
    const {access_token} =await this.fetchAccessToken();
    try {
      const res = await this.request({
        uri: urlConfig.ticket.fetch + access_token + "&type=jsapi"
      });
      if (res.ticket && res.expires_in) {
        const resticket = {
          ticket: res.ticket,
          expires_in: new Date().getTime() + (res.expires_in - 20) * 1000
        };
        await this.saveTicket(resticket);
        return res;
      } else {
        console.log("未获取ticket");
        return false;
      }
    } catch (e) {
      console.error(e);
    }
  }

  // 验证票据
  validData(val, key) {
    const now = new Date().getTime();
    if (val && val[key] && val.expires_in) {
      if (val.expires_in < now) {
        return false;
      }
      return true;
    } else {
      return false;
    }
  }

  // 处理请求
  async handle(name, ...arg) {
    const { access_token } = await this.fetchAccessToken();
    console.log(access_token);
    const opt = this[name](access_token, ...arg);
    const data = await this.request(opt);
    return data;
  }

  /* @标签 */
  // 创建标签
  createTag(token, name) {
    const from = {
      tag: { name }
    };
    const url = urlConfig.tag.create + token;
    return { method: "POST", url, body: from };
  }

  // 获取标签
  fetchTag(token, name) {
    const url = urlConfig.tag.fetch + token;
    return { method: "GET", url };
  }

  // 修改标签
  updateTag(token, id, name) {
    const from = {
      tag: { id, name }
    };
    const url = urlConfig.tag.update + token;
    return { method: "POST", url, body: from };
  }

  // 删除标签
  delTag(token, id) {
    const from = {
      tag: { id }
    };
    const url = urlConfig.tag.del + token;
    return { method: "POST", url, body: from };
  }

  // 获取用户列表
  fetchTageUsers(token, tagid, next_openid) {
    const from = {
      tagid,
      next_openid //第一个拉取的OPENID，不填默认从头开始拉取
    };
    const url = urlConfig.tag.fetchUsers + token;
    return { method: "POST", url, body: from };
  }

  // 批量为用户打标签
  batchTag(token, tagid, openid_list) {
    const from = {
      tagid,
      openid_list //第一个拉取的OPENID，不填默认从头开始拉取
    };
    const url = urlConfig.tag.batchTag + token;
    return { method: "POST", url, body: from };
  }

  // 批量为用户打标签
  batchUntag(token, tagid, openid_list) {
    const from = {
      tagid,
      openid_list //第一个拉取的OPENID，不填默认从头开始拉取
    };
    const url = urlConfig.tag.batchUntag + token;
    return { method: "POST", url, body: from };
  }

  // 设置用户备注名
  remarkUser(token, openid, remark) {
    const form = { openid, remark };
    const url = urlConfig.user.remark + token;
    return { method: "POST", url, body: form };
  }

  getUserInfo(token, openid, lang) {
    const url = `${urlConfig.user.info}${token}&openid=${openid}&lang=${lang ||
      "zh_CN"}`;
    return { url };
  }

  batchUserInfo(token, user_list) {
    const url = urlConfig.user.batchInfo + token;
    const form = { user_list };
    return { method: "POST", url, body: form };
  }

  fetchUserList(token, openid) {
    const url = `${urlConfig.user.fetchUserList}${token}&next_openid=${openid ||
      ""}`;
    return { url };
  }

  createMenu(token, menu) {
    const url = urlConfig.menu.create + token;

    return { method: "POST", url, body: menu };
  }

  getMenu(token) {
    const url = urlConfig.menu.get + token;
    return { url };
  }

  delMenu(token) {
    const url = urlConfig.menu.del + token;

    return { url };
  }

  addConditionMenu(token, button, matchrule) {
    const url = urlConfig.menu.addCondition + token;
    const form = { button, matchrule };

    return { method: "POST", url, body: form };
  }

  delConditionMenu(token, menuid) {
    const url = urlConfig.menu.delCondition + token;
    const form = { menuid };

    return { method: "POST", url, body: form };
  }

  getCurrentMenuInfo(token) {
    const url = urlConfig.menu.getInfo + token;

    return { url };
  }

  sign(ticket, url) {
    return sign(ticket, url);
  }
}
